import {题目类型} from './题目类型';
// @ts-ignore
import {Tag, Tags, Tags_Data, TagsNewFunction} from "./Tag.ts";
import {Ref, VNode,ToRefs} from "vue";
import {通用Topic} from "./题目类型标准/通用Topic";

/**
 * 你应该保证 所有题目 样式都是基于 原生题目字符串 而分析得出的
 * 即 ITopicView::view() 是基于 原生题目字符串 而展示
 * 尽量不要随意修改 topic_original(原生题目字符串) , 它需要保证 可以被分析
 */
export type topic_original = {
	/// 若你想监听它的变化,来去改变 自身其他状态,不如在构造函数中加一个 监听器
	topic_original:Ref<string>
};

/**
 * 题目核心接口
 *
 * 永远不要直接覆盖字段,比如 this.index = ref(0)
 *
 * 你应该在 构造类型 时初始化值后 ,随后一直使用那个值
 */
export interface ITopic<Topic extends topic_original> {
	/// 题目组名 ,代码部分地方叫 topic_group_name
	topics_name : Ref<string> //加个Ref吧,反正也没啥坏处
	index : Ref<number>
	type : Ref<题目类型>
	tag : Tags_Data //我认为它不需要强制Ref,交给外界选择
	topic: Topic //我选择把Ref交给外界选择
	resolve:Ref<string>
	/// 不建议修改
	/*readonly*/ self_new_view:ITopicView<Topic>
}

/**
 * 题目存储接口
 * 由于 序列化 后 不会序列化 函数,导致需要很麻烦的来处理它们
 * 其二是存储大小
 */
export type TopicStorage = {
	topics_name : string
	index : number
	type: 题目类型
	tag : {
		[tag_name: string]: any
	}
	topic_original: string
	resolve : string
}
/// ITopic 接口 转 TopicStorage 接口
export function ITopic_as_TopicStorage(topic:ITopic<any>):TopicStorage {
	let a : TopicStorage = {
		topics_name : topic.topics_name.value,
		index : topic.index.value,
		type: topic.type.value,
		tag : {},
		topic_original: topic.topic.topic_original.value,
		resolve : topic.resolve.value
	};
	for(let v in topic.tag){
		// @ts-ignore
		let b = TagsNewFunction[v].data_as_storage(topic.tag[v]);
		a.tag[v] = b;
	}
	return a;
}

/// TopicStorage 接口 + ITopic_Enum   转 ITopic 接口
export function TopicStorage_as_ITopic(topic_enum:ITopic_Enum,topic_storage:TopicStorage):ITopic<any> {
	let a : ITopic<any> = ITopic_Enum_new(topic_enum);
	a.topics_name.value = topic_storage.topics_name;
	a.index.value = topic_storage.index;
	/// 你可以 监听它 来去改变其他自定义状态
	a.topic.topic_original.value = topic_storage.topic_original;
	a.resolve.value = topic_storage.resolve;
	a.type.value = topic_storage.type;
	
	for(let v in topic_storage.tag){
		// @ts-ignore
		let b = TagsNewFunction[v].storage_as_data(topic_storage.tag[v],a.tag[v]);
		a.tag[v] = b;
	}
	
	return a;
}


/**
 * 我们需要一个有效构造对象的 标识符
 * 在存储时,会保证这个标识符,用来生成正确的对象
 */
export enum ITopic_Enum {
	通用Topic = "通用Topic"
}

export function ITopic_Enum_new(topic_enum:ITopic_Enum):ITopic<any>{
	let a:ITopic<any> = new 通用Topic();// 通用作为默认 ,多new就多new吧,优美优先
	switch (topic_enum) {
		case ITopic_Enum.通用Topic:a = new 通用Topic();break;
		// todo 持续扩展...
	}
	return a;
}


/**
 * 展示题目视图接口
 * 使用常量,而非class,蟹蟹
 */
export interface ITopicView<Topic extends topic_original>{
	// 返回一个 组件
	view(self:ITopic<Topic>):VNode
}


